构建多步骤表单 ⚡️ FormKit

您所在的位置:网站首页 react 表单多步填写 构建多步骤表单 ⚡️ FormKit

构建多步骤表单 ⚡️ FormKit

2024-07-18 04:23:40| 来源: 网络整理| 查看: 265

构建多步骤表单需求创建一个基本表单将表单分成几个部分跟踪每一步的有效性显示有效性显示错误添加一个组模糊事件错误 UI表单提交和接收错误整合在一起改进的方法官方多步骤插件

从1.0.0-beta.15开始,FormKit提供了一个官方的第一方插件,该插件创建了一个多步骤输入类型。

虽然理解如何自己构建多步骤输入仍然有价值,但如果你在寻找在项目中使用多步骤输入的最简单方法,请查看官方FormKit多步骤插件,它是免费和开源的!

在网络上,很少有交互会像面对一个大型、令人生畏的表单那样令人不悦。多步骤表单——有时被称为"向导"——可以通过将大型表单分解为更小、更易于接近的步骤来缓解这种痛苦,但它们也可能很复杂。

在本指南中,我们将一起构建一个使用FormKit的多步骤表单,并看看我们如何用最少的代码提供升级的用户体验。让我们开始吧!

组合API

本指南假设你熟悉Vue组合API。

需求

让我们首先列出我们的多部分表单的需求:

显示用户当前所在的步骤与所有必需步骤的关系。允许用户随意导航到表单的任何步骤。如果每个步骤都通过了所有前端验证,立即显示反馈✅。将所有步骤的表单数据汇总到一个对象中进行提交。在相应的字段和相应的步骤上显示任何返回的后端错误。创建一个基本表单

首先,让我们创建一个_没有步骤_的基本表单,这样我们就有内容可以使用了。我们的例子将是一个假设的申请接收补助的应用,所以我们将表单分为3个部分——"联系信息"、"组织信息"和"申请"。这些将在后面成为完整的表单步骤。

我们将为每个输入包含一组验证规则,并将每个部分限制为1个问题,直到我们有完整的结构。最后,为了本指南的目的,我们将在每个示例的底部输出收集的表单数据:

加载实时示例将表单分成几个部分

现在我们有了一个定义的结构,让我们将表单分成几个明确的部分。

首先,让我们用group ()包裹每个输入部分,这样我们就可以独立验证每个组。FormKit组强大的地方在于,它们能够了解所有子元素的验证状态,而不影响你的表单的标记。

当一个组的所有子元素(及其子元素)都有效时,该组本身就变得有效:

...

在我们的情况下,我们还需要包裹HTML。让我们将每个组放入一个"步骤"部分,我们可以有条件地显示和隐藏:

...

接下来,让我们引入一些导航UI,这样我们就可以在每个步骤之间切换:

// 现在,手动设置步骤名称 const stepNames = ['contactInfo', 'organizationInfo', 'application'] {{ camel2title(panel) }}

这是放在一起的样子:

样式不包括在内

多步骤表单的CSS——比如这个例子中的标签——不包含在默认的Genesis主题中。这个例子的样式是自定义编写的,你需要提供你自己的样式。

加载实时示例

它开始看起来像一个真正的多步骤表单了!但我们还有更多的工作要做,因为我们有几个问题:

没有显示每个单独步骤的有效性。当一个标签上有验证,但不是"当前步骤"时,它们无法被看到。

让我们解决第一个问题。

跟踪每一步的有效性

FormKit 已经默认跟踪 group 的有效性。我们只需要捕获这些数据,以便在我们的 UI 中使用它。

关于 FormKit 的一个重要概念是,每个 组件都有一个匹配的核心节点,它本身有一个反应性的 node.context 对象。这个 context 对象在 context.state.valid 中跟踪节点的有效性。如上所述,当一个 group 的所有后代都有效时,它就变得有效。有了这个概念,让我们构建一个对象,存储每个组的反应性有效性。

我们将利用 FormKit 的插件功能来完成这项工作。虽然 "插件" 这个词可能听起来很吓人,但在 FormKit 中,插件只是在创建节点时调用的设置函数。插件被所有后代(如组内的子节点)继承。

以下是我们的自定义插件,名为 stepPlugin:

// 我们的插件和我们的模板代码将使用 'steps' const steps = reactive({}) const stepPlugin = (node) => { // 只对 运行 if (node.props.type == 'group') { // 构建我们的 steps 对象 steps[node.name] = steps[node.name] || {} // 添加当前组的反应性有效性 node.on('created', () => { steps[node.name].valid = toRef(node.context.state, 'valid') }) // 停止插件继承到后代节点。 // 我们只关心代表步骤的顶级组 return false } }

我们上面的插件生成的 steps 反应性对象如下所示:

{ contactInfo: { valid: false }, organizationInfo: { valid: false } application: { valid: false } }

要使用我们的插件,我们将其添加到我们的根表单 。这意味着我们表单中的每个顶级组都将继承该插件:

... 表单的其余部分 显示有效性

现在我们的模板通过我们的插件实时访问每个组的有效性状态,让我们编写 UI 来在步骤导航栏中显示这些数据。

我们也不再需要手动定义我们的步骤,因为我们的插件正在动态存储 steps 对象中所有组的名称。如果步骤有效,让我们为每个步骤添加一个 data-step-valid="true" 属性,以便我们可以用 CSS 定位:

{{ camel2title(stepName) }}

有了这些更新,我们的表单现在能够在用户正确填写了给定步骤中的所有字段时通知他们!

我们还将进行一些其他改进:

将 "步骤逻辑" 提取到一个 Vue composable 中,以便在其他地方重用。为我们的实用函数创建一个 utils.js 文件。将我们找到的第一个步骤设置为 activeStep。加载实时示例显示错误

显示错误更为微妙。虽然用户可能并不知道,但实际上我们需要处理和向用户传达两种类型的错误:

未通过_前端_验证规则的错误(messages的类型为validation)后端错误(messages的类型为error)

FormKit使用其消息存储来跟踪这两种类型的错误/消息。

有了我们已经就位的插件,添加对这两者的跟踪相对简单:

const stepPlugin = (node) => { ... // 存储或更新阻塞验证消息的数量。 // FormKit每次数量变化时,都会发出"count:blocking"事件(带有计数)。 node.on('count:blocking', ({ payload: count }) => { steps[node.name].blockingCount = count }) // 存储或更新后端错误消息的数量。 node.on('count:errors', ({ payload: count }) => { steps[node.name].errorCount = count }) ... } 阻塞验证消息 vs 错误

FormKit区分前端验证消息(messages的类型为validation)和错误(messages的类型为error)。

让我们更新我们的示例,以显示这两种类型的错误,需满足以下要求:

如果存在后端错误,我们将始终显示其数量。只有当用户访问然后退出(模糊)一个组时,我们才会显示前端验证错误的数量——因为我们不希望在他们还在进行中时,用错误的用户界面对他们进行对抗。添加一个组模糊事件

由于"模糊一个组"在HTML中不存在,我们将在我们的插件中引入一个名为visitedSteps的数组来实现。以下是相关代码:

import { watch } from 'vue' import { getNode, createMessage } from '@formkit/core' const stepPlugin = (node) => { ... const activeStep = ref('') const visitedSteps = ref([]) // 跟踪访问过的步骤 // 观察我们的activeStep并存储访问过的步骤 watch(activeStep, (newStep, oldStep) => { if (oldStep && !visitedSteps.value.includes(oldStep)) { visitedSteps.value.push(oldStep) } // 如果一个组被访问过,触发在字段上显示验证 visitedSteps.value.forEach((step) => { const node = getNode(step) // node.walk()方法遍历当前节点的所有后代 // 并执行提供的函数。 node.walk((n) => { n.store.set( createMessage({ key: 'submitted', value: true, visible: false }) ) }) }) }) ... }

你可能会想知道为什么我们要遍历给定步骤的所有后代(node.walk())并创建一个键为submitted、值为true的消息?当用户试图提交表单时,这就是FormKit通知自己所有输入都处于submitted状态的方式。在这种状态下,FormKit强制任何阻塞验证消息出现。我们在"组模糊"事件中手动触发了同样的事情。

错误 UI

我们将为两种类型的错误使用相同的 UI,因为最终用户并不真正关心区别。以下是我们更新的步骤 HTML,它输出一个红色的气泡,显示错误的总和 errorCount + blockingCount:

{{ camel2title(stepName) }}

我们几乎到达终点了!以下是我们当前的表单 - 现在可以告诉用户他们是否正确或错误地填写了每一步:

加载实时示例表单提交和接收错误

最后一块拼图是提交表单并处理我们从后端服务器接收到的任何错误。为了本指南的目的,我们将模拟后端。

我们通过向 添加一个 @submit 处理器来提交表单:

... rest of form

以下是我们的提交处理器:

const submitApp = async (formData, node) => { try { const res = await axios.post(formData) node.clearErrors() alert('您的申请已成功提交!') } catch (err) { node.setErrors(err.formErrors, err.fieldErrors) } }

注意,FormKit 为我们的提交处理器传递了两个有用的参数:表单的数据在一个单一的请求就绪对象中(我们称之为 formData),以及表单的底层核心 node,我们可以使用它来清除错误或使用 node.clearErrors() 和 node.setErrors() 辅助函数分别设置任何返回的错误。

setErrors() 接受两个参数:表单级别的错误和字段特定的错误。我们的假后端返回 err 响应,我们用它来设置任何错误。

那么,如果用户在提交时处于步骤 3(申请),并且在隐藏的步骤上有字段级别的错误,会发生什么呢?幸运的是,只要节点存在于 DOM 中,FormKit 就能够适当地放置这些错误。这就是为什么我们使用 v-show 而不是 v-if 来显示步骤 - DOM 节点需要存在,以便在相应的 FormKit 节点上设置错误。

整合在一起

瞧!🎉 我们完成了!除了我们的提交处理程序,我们还在这个最终表单中添加了一些更多的UI和UX修饰,使其感觉更真实:

添加了用于步骤导航的上一步/下一步按钮。在utils.js中添加了一个返回错误的假后端。现在,只有当整个表单处于valid状态时,提交按钮才能启用。在表单中添加了一些额外的文本,以更好地模拟真实世界的UI。

这就是它 - 一个完全功能的多步骤表单:

加载实时示例想看看如何使用FormKit Schema构建吗?查看Playground 改进的方法

当然,任何事情都有改进的方法,这个表单也不例外。以下是一些想法:

将表单状态保存到window.localStorage,以便即使用户意外离开,也能保持用户的表单状态。预填充任何已知的表单值,这样用户就不必填写已知的数据。添加一个"尚未提交"的状态指示器,以警告用户他们仍需要提交。

我们在这个指南中涵盖了很多主题,希望你对FormKit以及如何使用它来简化多步骤表单有了更多的了解!

想在你的项目中使用多步输入吗?试试官方插件


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭